import { RefreshFormService } from '@farris/designer-services';
import { IdService } from '@farris/ui-common';
import { MessagerService } from '@farris/ui-messager';
import { TableTdManager } from './td-manager';

/**
 * 简单表格单元格菜单管理类
 */
export class SimpleTableTdManager extends TableTdManager {


    /**
     * 获取菜单配置
     */
    getMenuConfig() {

        this.menuConfig = [] as any[];

        this.menuConfig.push(
            {
                id: 'insertColumnToLeft',
                title: '左插入列',
                handle: () => this.insertColumnToLeft(),
            },
            {
                id: 'insertColumnToRight',
                title: '右插入列',
                handle: () => this.insertColumnToRight()
            },
            {
                id: 'insertRowToTop',
                title: '上插入行',
                handle: () => this.insertRowToTop()
            },
            {
                id: 'insertRowToBottom',
                title: '下插入行',
                handle: () => this.insertRowToBottom()
            },
            '-',
            {
                id: 'mergeColumnToRight',
                title: '向右合并',
                divider: true,
                handle: () => this.mergeColumnsToRight(),
                disable: !this.showMergeColumnToRight()
            },
            '-',
            {
                id: 'splitColumns',
                title: '拆分成列',
                divider: true,
                handle: () => this.splitColumns(),
                disable: !this.showSplitColumns()

            },
            '-',
            {
                id: 'removeColumn',
                title: '删除当前列',
                divider: true,
                handle: () => this.removeColumn(),
                disable: !this.showRemoveColumn()
            },
            {
                id: 'removeRow',
                title: '删除当前行',
                handle: () => this.removeRow(),
                disable: !this.showRemoveRow()
            },
            '-',
            {
                id: 'clearBinding',
                title: '清空内容',
                handle: () => this.clearTdBinding(),
                disable: !this.showClearTdBinding()
            }
        );

    }
    /**
     * 向左插入列
     */
    insertColumnToLeft() {
        const idService = this.injector.get(IdService);

        const staticTextTdIndex = this.selectedColumnIndex - 1;
        if (staticTextTdIndex < 0) {
            return;
        }

        // 在标签类单元格的左侧插入三列，作为一个分组
        this.tableTdHelper.insertColumns(this.component.rows, staticTextTdIndex);
        this.tableTdHelper.insertColumns(this.component.rows, staticTextTdIndex);
        this.tableTdHelper.insertColumns(this.component.rows, staticTextTdIndex);

        for (let rowIndex = 0; rowIndex < this.component.rows.length; rowIndex++) {
            let groupId = idService.generate();
            const newStaticTextTd = this.component.rows[rowIndex].columns[staticTextTdIndex];
            const newEditorTd = this.component.rows[rowIndex].columns[staticTextTdIndex + 1];
            const newInvisibleTd = this.component.rows[rowIndex].columns[staticTextTdIndex + 2];

            newStaticTextTd.tdType = 'staticText';
            newStaticTextTd.appearance.class = 'farris-group-wrap--label';
            newEditorTd.colspan = 2;

            // 若同列没有合并分组的情况，markCol就是空的，这时候需要手动配置markCol和markRow
            if (!newStaticTextTd.markCol) {
                newEditorTd.markCol = 0;
                newEditorTd.markRow = 0;

                newInvisibleTd.markCol = 1;
                newInvisibleTd.markRow = 0;
                newInvisibleTd.invisible = true;

            } else {
                // 若同列有合并分组的情况，这时候markCol已经是计算好的，不需要再手动配置。因为新增的列被自动合并了，所以groupId要取前一列的值
                if (staticTextTdIndex - 1 >= 0) {
                    const preColumn = this.component.rows[rowIndex].columns[staticTextTdIndex - 1];
                    groupId = preColumn.groupId;
                }
            }

            newStaticTextTd.groupId = groupId;
            newEditorTd.groupId = groupId;
            newInvisibleTd.groupId = groupId;
        }

        this.selectedColumnIndex = this.selectedColumnIndex + 3;
        this.redrawTable.next();
    }

    /**
     * 向右插入列
     */
    insertColumnToRight() {
        const targetColumnIndex = this.targetColumn.colspan > 1 ?
            this.tableTdHelper.findNextColIndex(this.selectedRowIndex, this.selectedColumnIndex + 1, this.component.rows) :
            this.selectedColumnIndex + 1;

        // 在右侧插入三列，作为一个分组
        this.tableTdHelper.insertColumns(this.component.rows, targetColumnIndex);
        this.tableTdHelper.insertColumns(this.component.rows, targetColumnIndex);
        this.tableTdHelper.insertColumns(this.component.rows, targetColumnIndex);

        const idService = this.injector.get(IdService);

        for (let rowIndex = 0; rowIndex < this.component.rows.length; rowIndex++) {
            let groupId = idService.generate();
            const newStaticTextTd = this.component.rows[rowIndex].columns[targetColumnIndex];
            const newEditorTd = this.component.rows[rowIndex].columns[targetColumnIndex + 1];
            const newInvisibleTd = this.component.rows[rowIndex].columns[targetColumnIndex + 2];

            newStaticTextTd.tdType = 'staticText';
            newStaticTextTd.appearance.class = 'farris-group-wrap--label';
            newEditorTd.colspan = 2;

            // 若同列没有合并分组的情况，markCol就是空的，这时候需要手动配置markCol和markRow
            if (!newStaticTextTd.markCol) {
                newEditorTd.markCol = 0;
                newEditorTd.markRow = 0;

                newInvisibleTd.markCol = 1;
                newInvisibleTd.markRow = 0;
                newInvisibleTd.invisible = true;

            } else {
                // 若同列有合并分组的情况，这时候markCol已经是计算好的，不需要再手动配置。因为新增的列被自动合并了，所以groupId要取前一列的值
                if (targetColumnIndex - 1 >= 0) {
                    const preColumn = this.component.rows[rowIndex].columns[targetColumnIndex - 1];
                    groupId = preColumn.groupId;
                }
            }

            newStaticTextTd.groupId = groupId;
            newEditorTd.groupId = groupId;
            newInvisibleTd.groupId = groupId;
        }

        this.redrawTable.next();
    }

    /**
     * 向上插入行
     */
    insertRowToTop() {
        this.tableTdHelper.insertRow(this.selectedRowIndex, this.component.rows);

        // 将新增行改造为【1个标签单元格+2个编辑器单元格的】分组
        this.changeTableTdIntoGroup(this.component.rows[this.selectedRowIndex].columns);


        this.selectedRowIndex++;
        this.redrawTable.next();
    }

    /**
     * 向下插入行
     */
    insertRowToBottom() {
        const targetRowIndex = this.targetColumn.rowspan > 1 ?
            this.tableTdHelper.findNextRowIndex(this.selectedRowIndex + 1, this.selectedColumnIndex, this.component.rows) :
            this.selectedRowIndex + 1;
        this.tableTdHelper.insertRow(targetRowIndex, this.component.rows);

        // 将新增行改造为【1个标签单元格+2个编辑器单元格的】分组
        this.changeTableTdIntoGroup(this.component.rows[targetRowIndex].columns);

        this.redrawTable.next();
    }

    /**
     * 将新增行改造为【1个标签单元格+2个编辑器单元格的】分组
     * @param columns 新增行的列配置
     */
    private changeTableTdIntoGroup(columns: any[]) {
        const idService = this.injector.get(IdService);

        if (columns.length && columns.length % 3 === 0) {
            for (let index = 0; index < columns.length; index += 3) {
                const groupId = idService.generate();

                const staticTextTd = columns[index];
                const editorTd = columns[index + 1];
                const invisibleTd = columns[index + 2];

                staticTextTd.tdType = 'staticText';
                staticTextTd.appearance.class = 'farris-group-wrap--label';
                staticTextTd.groupId = groupId;

                editorTd.colspan = 2;
                editorTd.markCol = 0;
                editorTd.markRow = 0;
                editorTd.groupId = groupId;

                invisibleTd.markCol = 1;
                invisibleTd.markRow = 0;
                invisibleTd.invisible = true;
                invisibleTd.groupId = groupId;

            }
        }

    }
    /**
     * 向右合并列：按分组合并
     */
    mergeColumnsToRight() {
        const targetColspan = this.targetColumn.colspan;
        const o = this.selectedColumnIndex + targetColspan;
        const rightColumn = this.component.rows[this.selectedRowIndex].columns[o];

        // 定位到右侧所有同组的的单元格
        const rightColumnsInSameGroup = this.component.rows[this.selectedRowIndex].columns.filter(column => column.groupId && column.groupId === rightColumn.groupId);

        // 检测右侧同组的单元格中是否包含编辑器类的单元格，若有，需要进行提示
        const editorTd = rightColumnsInSameGroup.find(column => column.tdType === 'editor' && column.editor && column.editor.type);

        if (editorTd) {
            const msgService = this.injector.get(MessagerService);
            msgService.question('合并后将重置右侧单元格的编辑器，确定合并？', () => {
                this.confirmMergeColumnsToRight(rightColumnsInSameGroup);
            });
        } else {
            this.confirmMergeColumnsToRight(rightColumnsInSameGroup);

        }

    }

    /**
     * 确认向右合并列：按分组合并
     */
    confirmMergeColumnsToRight(rightColumnsInSameGroup: any[]) {
        rightColumnsInSameGroup.forEach(column => {
            // 被合并列的分组id设置为当前列的分组id
            column.groupId = this.targetColumn.groupId;

            // 若单元格是显式的，需要触发合并单个单元格
            if (!column.invisible) {
                const targetColspan = this.targetColumn.colspan;
                const o = this.selectedColumnIndex + targetColspan;
                const rightColumn = this.component.rows[this.selectedRowIndex].columns[o];
                if (rightColumn.editor && rightColumn.editor.type) {

                    // 同步ViewModel
                    this.removeDesignViewModelFieldInColumns([rightColumn]);

                    this.confirmToMergeColumnToRight(rightColumn, targetColspan);

                } else {
                    this.confirmToMergeColumnToRight(rightColumn, targetColspan);
                }
            }
        });
    }

    /**
     * 拆分成列是否可用：判断单元格所在的分组是否为6/9/12...列，若是，可以拆分成2/3/4...个组
     */
    showSplitColumns(): boolean {
        const columnsInSameGroup = this.component.rows[this.selectedRowIndex].columns.filter(column => column.groupId && column.groupId === this.targetColumn.groupId);

        if (columnsInSameGroup && columnsInSameGroup.length && columnsInSameGroup.length > 3 && columnsInSameGroup.length % 3 === 0) {
            return true;
        }
        return false;

    }

    /**
     * 拆分成列：三个单元格为一个分组
     */
    splitColumns() {
        const idService = this.injector.get(IdService);
        this.targetMergedTdIds = [];

        // 同组的的单元格
        const columnsInSameGroup = this.component.rows[this.selectedRowIndex].columns.filter(column => column.groupId && column.groupId === this.targetColumn.groupId);

        for (let index = 0; index < columnsInSameGroup.length; index += 3) {
            const groupId = idService.generate();

            const staticTextTd = columnsInSameGroup[index];
            const editorTd = columnsInSameGroup[index + 1];
            const invisibleTd = columnsInSameGroup[index + 2];

            staticTextTd.tdType = 'staticText';
            staticTextTd.invisible = false;
            staticTextTd.colspan = 1;
            staticTextTd.markCol = 0;
            staticTextTd.markRow = 0;
            staticTextTd.groupId = groupId;

            editorTd.tdType = 'editor';
            editorTd.invisible = false;
            editorTd.colspan = 2;
            editorTd.markCol = 0;
            editorTd.markRow = 0;
            editorTd.groupId = groupId;

            invisibleTd.invisible = true;
            invisibleTd.markCol = 1;
            invisibleTd.markRow = 0;
            invisibleTd.groupId = groupId;

            if (index === 0) {
                this.targetMergedTdIds.push(staticTextTd.id);
                this.targetMergedTdIds.push(editorTd.id);
                this.targetMergedTdIds.push(invisibleTd.id);
            }
        }

        this.redrawTable.next();
    }

    /**
     * 是否支持删除列：合并后的列分组不支持移除；若同列的单元格有合并分组的情况，也不支持删除列
     * @returns boolean
     */
    showRemoveColumn(): boolean {
        const rows = this.component.rows;
        // 只有一个列分组，不能删除
        if (rows[this.selectedRowIndex].columns && rows[this.selectedRowIndex].columns.length === 3) {
            return false;
        }

        // 校验同列的单元格是否为1个分组
        for (let rowIndex = 0; rowIndex < rows.length; rowIndex++) {
            const targetColumn = rows[rowIndex].columns[this.selectedColumnIndex];
            // 同组的的单元格
            const columnsInSameGroup = rows[rowIndex].columns.filter(co => co.groupId && co.groupId === targetColumn.groupId);

            if (!columnsInSameGroup || !columnsInSameGroup.length || columnsInSameGroup.length !== 3) {
                return false;
            }
        }

        return true;

    }

    /**
     * 移除当前列分组
     */
    removeColumn() {

        const hasEditor = this.checkIfHasEditorInColumn();
        if (hasEditor) {
            const msgService = this.injector.get(MessagerService);
            msgService.question('确定移除当前列所有的编辑器配置？', () => {
                this.confirmRemoveColumn();
            });
        } else {
            this.confirmRemoveColumn();
        }
    }

    /**
     * 确定移除当前列
     */
    confirmRemoveColumn() {
        const rows = this.component.rows;

        let deletedColumns = [];
        for (let rowIndex = 0; rowIndex < rows.length; rowIndex++) {
            const targetColumn = rows[rowIndex].columns[this.selectedColumnIndex];
            deletedColumns = deletedColumns.concat(rows[rowIndex].columns.filter(co => co.groupId && co.groupId === targetColumn.groupId));

            rows[rowIndex].columns = rows[rowIndex].columns.filter(co => co.groupId !== targetColumn.groupId);
        }


        this.removeDesignViewModelFieldInColumns(deletedColumns);

        this.redrawTable.next({
            clearPropertyPanel: true
        });
    }

    /**
     * 是否支持移除行：合并后的行不支持移除
     * @returns boolean
     */
    showRemoveRow(): boolean {
        const rows = this.component.rows;
        // 若只有一行，不能删除
        if (rows.length < 2) {
            return false;
        }
        // 若同行的单元格有合并行的情况，也不支持删除
        for (let colIndex = 0; colIndex < rows[this.selectedRowIndex].columns.length; colIndex++) {
            const column = rows[this.selectedRowIndex].columns[colIndex];

            // 被合并的单元格
            if (column.invisible && column.markRow > 0) {
                return false;
            }

            // 合并单元格
            if (!column.invisible && !column.markRow && column.rowspan > 1) {
                return false;
            }
        }

        return true;
    }

    /**
     * 移除当前行
     */
    removeRow() {

        const hasEditor = this.checkIfHasEditorInRow();
        if (hasEditor) {
            const msgService = this.injector.get(MessagerService);
            msgService.question('确定移除当前行所有的编辑器配置？', () => {
                this.confirmRemoveRow();
            });
        } else {
            this.confirmRemoveRow();
        }

    }

    /**
     * 确认移除当前行
     */
    confirmRemoveRow() {
        const rows = this.component.rows;

        this.removeDesignViewModelFieldInColumns(rows[this.selectedRowIndex].columns);

        rows.splice(this.selectedRowIndex, 1);

        this.redrawTable.next({
            clearPropertyPanel: true
        });
    }

    /**
     * 清除单元格的绑定内容
     */
    private showClearTdBinding() {

        const rows = this.component.rows;
        const editorTd = rows[this.selectedRowIndex].columns[this.selectedColumnIndex];
        if (editorTd && editorTd.tdType === 'editor' && editorTd.editor && editorTd.editor.binding) {
            return true;
        }

        return false;
    }
    private clearTdBinding() {
        const rows = this.component.rows;
        const editorTd = rows[this.selectedRowIndex].columns[this.selectedColumnIndex];

        // 清除编辑器
        this.removeDesignViewModelFieldInColumns([editorTd]);
        editorTd.editor = { binding: null, type: null };

        // 定位到所有同组的标签单元格，清除文本内容
        const labelTdsInSameGroup = this.component.rows[this.selectedRowIndex].columns.filter(column => column.groupId && column.groupId === editorTd.groupId && column.tdType === 'staticText');
        if (labelTdsInSameGroup && labelTdsInSameGroup.length) {
            labelTdsInSameGroup.forEach(labelTd => {
                if (labelTd && labelTd.staticText) {
                    labelTd.staticText.text = '';
                    labelTd.staticText.require = false;
                }
            });
        }

        // 重绘
        this.redrawTable.next({
            refreshPropertyPanel: true
        });

        // 刷新实体树
        const refreshFormService = this.injector.get(RefreshFormService);
        refreshFormService.refreshSchamaTree.next();
    }
}

